package com.lc.communication.service;

import cn.hutool.core.lang.UUID;
import cn.hutool.core.thread.ThreadUtil;
import cn.hutool.json.JSONUtil;
import cn.hutool.log.Log;
import com.lc.communication.config.LcConfig;
import com.lc.communication.constants.ChannelConstant;
import com.lc.communication.util.ChannelMap;
import com.lc.communication.vo.RequestVo;
import io.netty.channel.Channel;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.AsyncResult;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.concurrent.Future;

/**
 * @author liuhf17
 * @version 1.0.0
 * @ClassName NettyService.java
 * @Description TODO
 * @createTime 2024年06月14日 14:19:00
 */
@Service
public class NettyService {
    private static final Log log = Log.get();

    @Resource
    private LcConfig lcConfig;

    @Async
    public Future<Object> doSomethingAsync(RequestVo vo) {
        String clientName = vo.getClientName();
        //生成请求唯一id
        if (vo.getId() == null || "".equals(vo.getId())) {
            vo.setId(UUID.randomUUID().toString());
        }
        vo.setType(ChannelConstant.REQUEST_MSG);
        vo.setClientName(clientName);
        String clientUuid = ChannelMap.CLIENT_NAME_UUID.get(clientName);
        vo.setClientUuid(clientUuid);

        if (null == clientUuid) {
            vo.setError("客户端未连接");
            vo.setType(ChannelConstant.ERROR);
            return new AsyncResult<>(vo);
        }
        //确定从哪个服务端发出，发给客户端
        Channel channel = ChannelMap.CHANNEL_CLIENT_MAP.get(clientUuid);
        if (channel != null) {
            //记录请求用于获取返回值
            ChannelMap.resultMap.put(vo.getId(), ChannelConstant.WAIT);
            log.info("发送请求 id：{}", vo.getId());
            channel.writeAndFlush(vo.toRequestVo());
            return new AsyncResult<>(ChannelMap.getRequestResult(vo));
        } else {
            log.error("CHANNEL_SERVER_MAP:{},CLIENT_NAME_UUID:{}", JSONUtil.toJsonStr(ChannelMap.CHANNEL_CLIENT_MAP.keySet()),
                    JSONUtil.toJsonStr(ChannelMap.CLIENT_NAME_UUID));
            vo.setType(ChannelConstant.ERROR);
            vo.setError("channel获取失败");
            return new AsyncResult<>(vo);
        }
        //return new AsyncResult<>("Async response from Spring");
    }


    @PostConstruct
    public void init() {
        if (lcConfig.isServerStart()) {
            new Thread(() -> HeartBeatServer.start(lcConfig.getServerPort())).start();
        }
        //三秒后启动客户端
        //ThreadUtil.sleep(3000);
        if (lcConfig.isClientStart()) {
            ThreadUtil.sleep(ChannelConstant.SERVER_HEART_TIME);
            new Thread(() -> HeartBeatClient.start(lcConfig.getClientName(),
                    lcConfig.getServerHost(), lcConfig.getClientPort())).start();
        }
    }
}
